import json

from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import SKU

"""
①  有些网站登录才可以实现 购物车								v

​	有些网站不登录也可以实现购物车



② 登录可以把购物车的信息保存到 服务器					v

​	未登录可以把购物车的信息保存到 客户端[cookie]



③  mysql   还是 redis

​	单独保存在mysql可以，单独保存在redis 也可以， 既保存在mysql又保存redis也可以。

 	单独保存在redis 也可以 【学习角度考虑】



④ 保存哪些数据

​	用户id,商品id，商品数量，勾选状态



⑤	redis的数据类型

一。先实现功能 

二。再实现功能的前提下。尽量少的占用内存空间



string		key:value

hash		 key:		field:value,field:value

list			key:		[1,3,4,2]

set			key:       {2,4,7,1}

zset			key:     {2,4,7,9}



抽象的问题具体化！



用户id,商品id，商品数量，勾选状态

  666

​			  1			10				v

​				2			20			

​				3			30				v

​			    4			40				



hash  	商品id，商品数量

 set 		{选择的商品id,选中的商品id}



hash  	商品id，[+- 表示 选中未选中]商品数量

"""


"""
购物车的增删改查

增
        前端:         当用户点击添加购物车的时候,会发送ajax请求 .请求携带 商品id,商品数量.请求头中携带cookie [sessionid]
                      添加购物车默认选中,所以 选中状态 提交可选
        后端:
            请求:
                        POST            /carts/         body   JSOn
            业务:
                        1. 接收参数
                        2. 提取参数
                        3. 验证参数
                        4. 数据入库(redis)
                            4.1 链接redi
                            4.2 操作hash
                            4.3 操作set
                        5. 返回响应 
            响应:
                        code:0

查
        前端:         访问购物车列表页面
        后端:
                请求:     GET     /carts/
                业务:
                        1.根据需求查询数据 (redis)
                            1.1 链接redis
                            1.2 获取hash
                            1.3 获取set
                            1.4 根据商品的id查询商品的详细信息
                        2.将对象转换为字典数据
                        3.返回响应
                响应:

改
        ① 只要修改了一个商品的数量或者是选中状态 就发送请求
        ② 发送修改的数据 有 商品id和商品数量 以及 选中状态
        ③ 传递数量 可以传递 +1或者-1  也可以传递最终的数量值 7 10
        
        前端:
                当用户修改选中状态 或者修改数量的时候.发送ajax 请求.  商品id和商品数量 以及 选中状态
        后端:
        
            请求:     PUT         /carts/         body        JSON
            逻辑:
                       
                        1. 接收参数
                        2. 提取参数
                        3. 验证参数
                        4. 数据更新
                            4.1 链接redis
                            4.2 更新hash
                            4.3 更新set
                        5. 返回响应   
            响应:
                    code:0 ,count: 最终的数量

删   
        前端:
                用户点击删除按钮, 前端发送ajax请求. 请求携带 sku_id
        后端:
            请求:
                    DELETE      carts/      body    JSON
                    
            逻辑:
                    1.接收数据
                    2.提取数据
                    3.根据id查询数据
                    4.删除数据
                        4.1 链接redis
                        4.2 删除hash
                        4.3 删除set
                    5.返回响应
            响应:
                    code:0
"""
from utils.user import LoginRequiredJSONMixin
class CartView(LoginRequiredJSONMixin,View):

    def post(self,request):
        # 1. 接收参数
        data = json.loads(request.body.decode())
        # 2. 提取参数
        sku_id = data.get('sku_id')
        count = data.get('count')
        # 3. 验证参数
        # 3.1 判断商品id 是否存储
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code':400,'errmsg':'没有此商品'})
        # 3.2 count 应该是 数值
        try:
            count = int(count)
        except Exception:
            count = 1
        # 4. 数据入库(redis)
        #     4.1 链接redi
        redis_cli = get_redis_connection('carts')
        #     4.2 操作hash
        # redis_cli.hset('carts_%s'%request.user.id,sku_id,count)
        # 数量并没有累加
        # 方式1 先获取之前的数量 自己累加
        # 方式2 hincrby  数据累加
        redis_cli.hincrby('carts_%s'%request.user.id,sku_id,count)

        #     4.3 操作set
        redis_cli.sadd('selected_%s'%request.user.id,sku_id)
        # 5. 返回响应
        return JsonResponse({'code':0,'count':count})


    def get(self,request):
        # 1.根据需求查询数据 (redis)
        #     1.1 链接redis
        redis_cli = get_redis_connection('carts')
        #     1.2 获取hash
        sku_id_counts = redis_cli.hgetall('carts_%s'%request.user.id)
        # {1:10,2:20}
        #     1.3 获取set
        selected_ids = redis_cli.smembers('selected_%s'%request.user.id)
        # {1}
        #     1.4 根据商品的id查询商品的详细信息
        data_list = []
        for sku_id,count in sku_id_counts.items():
            sku = SKU.objects.get(id=sku_id)
            # 2.将对象转换为字典数据
            data_list.append({
                'id':sku.id,
                'count':int(count),                              #购物车数量
                'selected': sku_id in selected_ids,          #选中状态
                'amount':  int(count) * int(sku.price),               #商品金额小计
                'name':sku.name,
                'price':int(sku.price),
                'default_image_url':sku.default_image.url
            })
        # 3.返回响应
        return JsonResponse({
            "code": 0,
            "errmsg": "OK",
            "cart_skus": data_list
        })


    def put(self,request):

        # 1. 接收参数
        data = json.loads(request.body.decode())
        # 2. 提取参数
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected')
        # 3. 验证参数 (省略)
        # 4. 数据更新
        #     4.1 链接redis
        redis_cli = get_redis_connection('carts')
        #     4.2 更新hash
        redis_cli.hset('carts_%s'%request.user.id,sku_id,count)
        #     4.3 更新set
        if selected:
            redis_cli.sadd('selected_%s'%request.user.id,sku_id)
        else:
            redis_cli.srem('selected_%s'%request.user.id,sku_id)
        # 5. 返回响应
        return JsonResponse({'code':0,'cart_sku':{'count':count,'selected':selected}})


    def delete(self,request):
        # 1.接收数据
        data = json.loads(request.body.decode())
        # 2.提取数据
        sku_id = data.get('sku_id')
        # 3.根据id查询数据
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code':400,'errmsg':'数据不存在'})
        # 4.删除数据
        #     4.1 链接redis
        redis_cli = get_redis_connection('carts')
        #     4.2 删除hash
        redis_cli.hdel('carts_%s'%request.user.id,sku_id)
        #     4.3 删除set
        redis_cli.srem('selected_%s'%request.user.id,sku_id)
        # 5.返回响应
        return JsonResponse({'code':0})
